package com.ezhan.gui;

import com.ezhan.api.InstallPyLibService;
import com.ezhan.api.InstallSerivce;
import com.ezhan.api.Log;
import com.ezhan.api.MessageNotifier;
import com.ezhan.api.Service.InstallServiceImpl;
import com.ezhan.api.Service.PythonLibServiceImpl;
import com.ezhan.entity.Packages;
import com.ezhan.logging.LogManager;
import com.ezhan.message.NotifierManager;
import com.ezhan.utils.PathUtils;
import com.formdev.flatlaf.util.UIScale;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class InstallGUI extends JFrame implements Log, MessageNotifier {
    private final InstallSerivce installSerivce = new InstallServiceImpl();  //接口可以指向实现类对象
    private final InstallPyLibService installPyLibService = new PythonLibServiceImpl();
    private JProgressBar progressBar;
    private JTextArea logArea;
    private JButton installButton;
    private JCheckBox jdkCheckBox, mysqlCheckBox, pythonCheckBox, dbeaverCheckBox;
    private final ExecutorService executor = Executors.newSingleThreadExecutor();  //单个线程的线程池

    PathUtils exePath = new PathUtils();
    File parentDir = exePath.getExecutablePath().getParentFile(); // 获取 EXE 文件所在目录的上一级目录

    public InstallGUI() {
        initUI();
        LogManager.setLog(this);
        NotifierManager.setMessageNotifier(this);
        setTitle("机器人调度软件安装器");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  //关闭窗口，程序退出
        setLocationRelativeTo(null);  //位于屏幕中心
        setMinimumSize(new Dimension(UIScale.scale(500), UIScale.scale(500)));  //最小尺寸
    }

    public void initUI() {
        // 主面板使用单个边框设置（缩放版）
        JPanel mainPanel = new JPanel();
        mainPanel.setBorder(BorderFactory.createEmptyBorder(
                UIScale.scale(15), UIScale.scale(15),
                UIScale.scale(15), UIScale.scale(15)));
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));

        // 软件选择区域
        JPanel selectionPanel = new JPanel();
        selectionPanel.setLayout(new BoxLayout(selectionPanel, BoxLayout.Y_AXIS));

        // 创建复选框组件（使用默认字体）
        jdkCheckBox = new JCheckBox("安装 JDK 17 开发环境");
        jdkCheckBox.setSelected(true);
        mysqlCheckBox = new JCheckBox("安装 MySQL 8.0 数据库");
        mysqlCheckBox.setSelected(true);
        pythonCheckBox = new JCheckBox("安装 Python 3.8");
        pythonCheckBox.setSelected(true);
        dbeaverCheckBox = new JCheckBox("安装 DBeaver 数据库工具");
        dbeaverCheckBox.setSelected(true);

        // 添加到选择面板
        JPanel jdkPanel = new JPanel(new BorderLayout());
        jdkPanel.add(jdkCheckBox, BorderLayout.WEST);
        selectionPanel.add(jdkPanel);

        JPanel mysqlPanel = new JPanel(new BorderLayout());
        mysqlPanel.add(mysqlCheckBox, BorderLayout.WEST);
        selectionPanel.add(mysqlPanel);

        JPanel pythonPanel = new JPanel(new BorderLayout());
        pythonPanel.add(pythonCheckBox, BorderLayout.WEST);
        selectionPanel.add(pythonPanel);

        JPanel dbeaverPanel = new JPanel(new BorderLayout());
        dbeaverPanel.add(dbeaverCheckBox, BorderLayout.WEST);
        selectionPanel.add(dbeaverPanel);

        selectionPanel.setAlignmentX(Component.LEFT_ALIGNMENT);

        // 选择容器
        JPanel selectionContainer = new JPanel(new BorderLayout());
        selectionContainer.setBorder(BorderFactory.createTitledBorder("选择安装组件"));
        selectionContainer.add(selectionPanel, BorderLayout.CENTER);
        selectionContainer.setAlignmentX(Component.LEFT_ALIGNMENT);
        mainPanel.add(selectionContainer);
        mainPanel.add(Box.createRigidArea(new Dimension(0, UIScale.scale(15))));

        // 日志区域
        int rows = UIScale.scale(10);
        int columns = UIScale.scale(40);
        logArea = new JTextArea(rows, columns);
        logArea.setEditable(false);
        logArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, UIScale.scale(12)));
        JScrollPane scrollPane = new JScrollPane(logArea);
        scrollPane.setBorder(BorderFactory.createTitledBorder("安装日志"));
        scrollPane.setAlignmentX(Component.LEFT_ALIGNMENT);
        mainPanel.add(scrollPane);
        mainPanel.add(Box.createRigidArea(new Dimension(0, UIScale.scale(15))));

        // 进度条
        progressBar = new JProgressBar();
        progressBar.setStringPainted(true);
        progressBar.setAlignmentX(Component.LEFT_ALIGNMENT);
        progressBar.setPreferredSize(new Dimension(
                Integer.MAX_VALUE, UIScale.scale(20)));
        mainPanel.add(progressBar);
        mainPanel.add(Box.createRigidArea(new Dimension(0, UIScale.scale(10))));

        // 按钮区域 - 先创建按钮再设置属性
        installButton = new JButton("开始安装");
        installButton.setFont(new Font("微软雅黑", Font.BOLD, UIScale.scale(14)));
        installButton.setPreferredSize(new Dimension(
                UIScale.scale(150), UIScale.scale(40)));
        installButton.addActionListener(e -> startInstallation());

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER,
                UIScale.scale(10), UIScale.scale(10)));
        buttonPanel.add(installButton);
        buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
        mainPanel.add(buttonPanel);

        // 添加主面板到窗口
        add(mainPanel, BorderLayout.CENTER);
        setMinimumSize(new Dimension(UIScale.scale(500), UIScale.scale(500)));
    }

    //开始安装
    private void startInstallation() {
        // 重置界面状态
        installButton.setEnabled(false);
        jdkCheckBox.setEnabled(false);
        mysqlCheckBox.setEnabled(false);
        pythonCheckBox.setEnabled(false);
        dbeaverCheckBox.setEnabled(false);
        logArea.setText("");
        progressBar.setValue(0);


        // 开始安装
        executor.execute(() -> {
            try {
                log("正在检查系统权限...");
                if (!checkAdminPrivileges()) {
                    log("错误: 需要管理员权限运行程序");
                    showError("请以管理员身份运行此程序");
                    resetInstallButton();
                    return;
                }


                int packagesToInstall = (jdkCheckBox.isSelected() ? 1 : 0) +
                        (mysqlCheckBox.isSelected() ? 1 : 0) +
                        (pythonCheckBox.isSelected() ? 1 : 0) +
                        (dbeaverCheckBox.isSelected() ? 1 : 0);

                if (packagesToInstall == 0) {
                    log("错误: 未选择任何安装组件");
                    showError("请至少选择一个安装组件");
                    resetInstallButton();
                    return;
                }

                int packagesInstalled = 0;

                // 安装JDK
                if (jdkCheckBox.isSelected()) {
                    String installPath = parentDir.getAbsolutePath() + "\\Java\\jdk-17";
                    if (installSerivce.installPackage(Packages.getPackageInfo("JDK"), installPath, parentDir)) {
                        packagesInstalled++;
                        updateProgress(packagesInstalled, packagesToInstall);
                    }
                }

                // 安装MySQL
                if (mysqlCheckBox.isSelected()) {
                    String installPath = parentDir.getAbsolutePath() + "\\MySQL";
                    if (installSerivce.installPackage(Packages.getPackageInfo("MySQL"), installPath, parentDir)) {
                        packagesInstalled++;
                        updateProgress(packagesInstalled, packagesToInstall);
                    }
                }

                // 安装Python
                if (pythonCheckBox.isSelected()) {
                    String installPath = parentDir.getAbsolutePath() + "\\Python38";
                    String installPythonLib = installPath + "\\python.exe";   //python.exe
                    String pythonLib = parentDir.getAbsolutePath() + "\\python_env\\lib_all"; // pythonLib目录
                    if (installSerivce.installPackage(Packages.getPackageInfo("Python"), installPath, parentDir)) {
                        installPyLibService.executePythonLibInstallations(installPythonLib, pythonLib);
                        packagesInstalled++;
                        updateProgress(packagesInstalled, packagesToInstall);
                    }
                }

                // 安装DBeaver
                if (dbeaverCheckBox.isSelected()) {
                    String installPath = parentDir.getAbsolutePath() + "\\Dbeaver";
                    if (installSerivce.installPackage(Packages.getPackageInfo("DBeaver"), installPath, parentDir)) {
                        packagesInstalled++;
                        updateProgress(packagesInstalled, packagesToInstall);
                    }
                }

                if (packagesInstalled == packagesToInstall) {
                    log("所有安装已完成!");
                    log("请根据需要进行必要配置");
                    showSuccess("安装成功!");
                } else {
                    log("部分安装未完成，请检查错误日志");
                    showError("安装部分完成，请检查日志");
                }
            } catch (Exception e) {
                log("安装过程中发生错误: " + e.getMessage());
                log("详细错误: ");
                StringWriter sw = new StringWriter();
                e.printStackTrace(new PrintWriter(sw));
                log(sw.toString());
                showError("安装失败: " + e.getMessage());
            } finally {
                resetInstallButton();
            }
        });
    }

    private void resetInstallButton() {
        SwingUtilities.invokeLater(() -> {
            installButton.setEnabled(true);
            jdkCheckBox.setEnabled(true);
            mysqlCheckBox.setEnabled(true);
            pythonCheckBox.setEnabled(true);
            dbeaverCheckBox.setEnabled(true);
        });
    }

    //检查管理员权限
    private boolean checkAdminPrivileges() {
        try {
            if (System.getProperty("os.name").toLowerCase().contains("win")) {
                // Windows: 尝试在系统目录创建测试文件,Paths.get创建文件路径对象
                Path testPath = Paths.get(System.getenv("SystemRoot"), "test_admin.tmp");
                Files.write(testPath, "test".getBytes());
                Files.delete(testPath);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

    private void updateProgress(int installed, int total) {
        int progress = (int) (installed * 100.0 / total);
        SwingUtilities.invokeLater(() -> progressBar.setValue(progress));
    }

    @Override
    public void log(String message) {
        SwingUtilities.invokeLater(() -> {
            logArea.append("[" + new java.util.Date() + "] " + message + "\n");
            logArea.setCaretPosition(logArea.getDocument().getLength());
        });
    }

    @Override
    public void showSuccess(String message) {
        SwingUtilities.invokeLater(() ->
                JOptionPane.showMessageDialog(this, message, "安装成功", JOptionPane.INFORMATION_MESSAGE));
    }

    @Override
    public void showError(String message) {
        SwingUtilities.invokeLater(() ->
                JOptionPane.showMessageDialog(this, message, "安装错误", JOptionPane.ERROR_MESSAGE));
    }
}